﻿#include <net/tcpsession.h>
#include <net/netreading.h>
#include <net/netwriting.h>

#include <QTcpSocket>

QNET_USING_NAMESPACE

TcpSession::TcpSession(QObject *parent)
    :QObject (parent)
{
    m_reading = Q_NULLPTR;
    m_bManualClosed = false;
}

TcpSession::TcpSession(QTcpSocket *socket, QObject *parent)
    :QObject(parent)
{
    m_reading = Q_NULLPTR;
    m_socket = socket;
    connect(m_socket, &QIODevice::readyRead, this, &TcpSession::readyRead);
    connect(m_socket, &QAbstractSocket::stateChanged, this, &TcpSession::stateChanged);
    connect(m_socket, &QAbstractSocket::connected, this, &TcpSession::connected);
    connect(m_socket, &QAbstractSocket::disconnected, this, &TcpSession::disconnected);
    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SIGNAL(error(QAbstractSocket::SocketError)));
    connect(this, &TcpSession::onClose, this, &TcpSession::closeSlot);

    static int id = qRegisterMetaType<QSharedPointer<NetWriting>>("QSharedPointer<NetWriting>");
    Q_UNUSED(id)

    connect(this, &TcpSession::writeSignal, this, &TcpSession::writeSlot);
}

TcpSession::~TcpSession()
{
    m_socket = Q_NULLPTR;
}


bool TcpSession::write(QSharedPointer<NetWriting> writing)
{
    if(m_socket &&
            (m_socket->state()
             != QAbstractSocket::SocketState::ConnectedState))
        return false;

    emit writeSignal(writing);
    return true;
}

void TcpSession:: close()
{
    m_bManualClosed = true;
    emit onClose();
}

void TcpSession::readyRead()
{
    while(m_socket && m_socket->bytesAvailable())
    {
        qint64 length = m_socket->bytesAvailable();
        if(length < 0)
        {
            qDebug()<<" length < 0";
            continue;
        }
        //接收数据
        if(!m_socket)
        {
            break;
        }
        QByteArray readData = m_socket->read(length);
        if(readData.isEmpty())
        {
            break;
        }
        if(m_reading)
        {
            m_reading->onProc(readData);
        }
    }
}
void TcpSession::writeSlot(QSharedPointer<NetWriting> writing)
{
    if(m_socket &&
            (m_socket->state() !=
            QAbstractSocket::SocketState::ConnectedState))
    {
        emit writing->fulfil(writing, -1);
        return ;
    }
    QByteArray data = writing->data();
    qint64 size = m_socket->write(data);
    emit writing->fulfil(writing, int(size));
}

void TcpSession::closeSlot()
{
    if(m_socket)
    {
        m_socket->disconnectFromHost();
        m_socket = Q_NULLPTR;
    }
}

bool TcpSession::bManualClosed() const
{
    return m_bManualClosed;
}

void TcpSession::setReading(NetReading *reading)
{
    m_reading = reading;
    if(m_reading){
        m_reading->setHost(remoteIp());
        m_reading->setPort(remotePort());
    }
}

NetReading *TcpSession::reading() const
{
    return m_reading;
}

quint16 TcpSession::remotePort() const
{
    return m_socket->peerPort();
}

quint16 TcpSession::localPort() const
{
    return m_socket->localPort();
}

QHostAddress TcpSession::remoteIp() const
{
    return m_socket->peerAddress();
}

QHostAddress TcpSession::localIp() const
{
    return m_socket->localAddress();
}

ISessionListener::~ISessionListener()
{

}
